EFI TCG2 protocol in U-Boot and QEMU
Posted on Tue 31 August 2021 in UEFI • 5 min read
Do I need a TPM?
I won't go into details regarding why a TPM is useful. There is an excellent article from Matthew Garrett on that, but the short answer is "yes you do".
U-Boot Support
There's a spec defining a standard interface to the TPM on an UEFI platform. It's purpose is to define APIs and provide information, for things like, is a TPM present, which PCR banks are active, change active PCR banks, obtain the TCG boot log, extend hashes to PCRs, and append events to the TCG boot log etc.
U-Boot recently got support for this as well as support for the TCG PC Client Platform Firmware Profile.
Patches can be found here, here and here.
Finding an Arm device with with a TPMv2 can prove hard. So it would be useful to emulate that in software. If you have a board with an RPMB and OP-TEE support, I suggest you try Microsoft's fTPM. However testing that in QEMU won't work since it lacks RPMB emulation. Luckily there's another solution.
Using SWTPM
SWTPM is a TPM emulator that works under QEMU. It provides a memory mapped device which adheres to the TCG TPM Interface Specification. The problem is that U-Boot had no support for memory mapped TPMs, which is exactly what this patchset does.
Building U-Boot
At the time of this article the U-Boot patches are under review, so we need to
apply them manually.
So download the patches prepare your U-Boot binary. Patches are now in U-Boot mainline and the arm64 defconfig has the required config options enabled.
git clone https://github.com/u-boot/u-boot.git
pushd u-boot
make qemu_arm64_defconfig
make menuconfig
We need to enable the TPMv2 support in U-Boot
CONFIG_TPM
, CONFIG_CMD_TPM
, CONFIG_TPM2_MMIO
must be enabled. Once
those are selected CONFIG_EFI_TCG2_PROTOCOL
should be automatically included.
Make sure you enable CONFIG_CMD_EFIDEBUG
, since we will need it to boot our
kernel.
make -j $(nproc)
popd
Running QEMU
Make sure swtpm is installed and running on your system. For debian and friends there's a swtpm package, so just do
sudo apt install swtpm
mkdir /tmp/mytpm1
swtpm socket --tpmstate dir=/tmp/mytpm1 \
--ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \
--log level=40 --tpm2 &
and launch QEMU with swtpm support
sudo qemu-system-aarch64 \
-bios u-boot.bin \
-machine virt,gic-version=3,accel=kvm \
-cpu host -m 4G \
-nographic -no-acpi \
-chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
-tpmdev emulator,id=tpm0,chardev=chrtpm \
-device tpm-tis-device,tpmdev=tpm0 \
-drive id=disk0,file=rootfs-linaro-buster-raw-unknown-20200720-440.ext4,if=none,format=raw \
-device virtio-blk-device,drive=disk0
Booting linux
From U-Boot's command line do something along the lines of
tpm2 startup TPM2_SU_CLEAR && virtio scan
efidebug boot add -b ABE0 'kernel' virtio 0 boot/Image -s 'root=/dev/vda'
efidebug boot order ABE0
bootefi bootmgr
If everything is compiled and launched correctly, you should see the kernel reporting the location of some related EventLog pointers.
efi: EFI v2.80 by Das U-Boot
efi: TPMFinalLog=0x13ddcc040 RTPROP=0x13ddcb040 SMBIOS=0xffffe000 TPMEventLog=0x13ddc4040 MEMRESERVE=0x13ddc3040
Reading the EventLog
I am using a debian .ext4 image, where I have installed the latest tpm2 tools. If you don't have them install them with
sudo apt install tpm2-tools
The kernel exposes the eventlog in /sys. So you can read it with:
tpm2_eventlog /sys/kernel/security/tpm0/binary_bios_measurements
---
events:
- EventNum: 0
PCRIndex: 0
EventType: EV_NO_ACTION
Digest: "0000000000000000000000000000000000000000"
EventSize: 37
SpecID:
- Signature: Spec ID Event03
platformClass: 0
specVersionMinor: 0
specVersionMajor: 2
specErrata: 2
uintnSize: 2
numberOfAlgorithms: 2
Algorithms:
- Algorithm[0]:
algorithmId: sha1
digestSize: 20
- Algorithm[1]:
algorithmId: sha256
digestSize: 32
vendorInfoSize: 0
- EventNum: 1
PCRIndex: 0
EventType: EV_S_CRTM_VERSION
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "0772fd675fbebcdd4401008ee8d609760c1675df"
- AlgorithmId: sha256
Digest: "69f66450f9a8780cf2fbab358d46b8fabd4b7e9ae886b3d80083646c30e91b4c"
EventSize: 74
Event: "552d426f6f7420323032312e31302d7263322d30303031302d67643536666231666138352d646972747920284175672032342032303231202d2030363a33343a3335202b303830302900"
- EventNum: 2
PCRIndex: 7
EventType: EV_EFI_VARIABLE_DRIVER_CONFIG
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "57cd4dc19442475aa82743484f3b1caa88e142b8"
- AlgorithmId: sha256
Digest: "115aa827dbccfb44d216ad9ecfda56bdea620b860a94bed5b7a27bba1c4d02d8"
EventSize: 53
Event:
VariableName: 61dfe48b-ca93-d211-aa0d-00e098032b8c
UnicodeNameLength: 10
VariableDataLength: 1
UnicodeName: SecureBoot
VariableData: "00"
- EventNum: 3
PCRIndex: 7
EventType: EV_EFI_VARIABLE_DRIVER_CONFIG
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "9b1387306ebb7ff8e795e7be77563666bbf4516e"
- AlgorithmId: sha256
Digest: "dea7b80ab53a3daaa24d5cc46c64e1fa9ffd03739f90aadbd8c0867c4a5b4890"
EventSize: 36
Event:
VariableName: 61dfe48b-ca93-d211-aa0d-00e098032b8c
UnicodeNameLength: 2
VariableDataLength: 0
UnicodeName: PK
- EventNum: 4
PCRIndex: 7
EventType: EV_EFI_VARIABLE_DRIVER_CONFIG
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "9afa86c507419b8570c62167cb9486d9fc809758"
- AlgorithmId: sha256
Digest: "e670e121fcebd473b8bc41bb801301fc1d9afa33904f06f7149b74f12c47a68f"
EventSize: 38
Event:
VariableName: 61dfe48b-ca93-d211-aa0d-00e098032b8c
UnicodeNameLength: 3
VariableDataLength: 0
UnicodeName: KEK
- EventNum: 5
PCRIndex: 7
EventType: EV_EFI_VARIABLE_DRIVER_CONFIG
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "5bf8faa078d40ffbd03317c93398b01229a0e1e0"
- AlgorithmId: sha256
Digest: "baf89a3ccace52750c5f0128351e0422a41597a1adfd50822aa363b9d124ea7c"
EventSize: 36
Event:
VariableName: cbb219d7-3a3d-9645-a3bc-dad00e67656f
UnicodeNameLength: 2
VariableDataLength: 0
UnicodeName: db
- EventNum: 6
PCRIndex: 7
EventType: EV_EFI_VARIABLE_DRIVER_CONFIG
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "734424c9fe8fc71716c42096f4b74c88733b175e"
- AlgorithmId: sha256
Digest: "9f75b6823bff6af1024a4e2036719cdd548d3cbc2bf1de8e7ef4d0ed01f94bf9"
EventSize: 38
Event:
VariableName: cbb219d7-3a3d-9645-a3bc-dad00e67656f
UnicodeNameLength: 3
VariableDataLength: 0
UnicodeName: dbx
- EventNum: 7
PCRIndex: 4
EventType: EV_EFI_BOOT_SERVICES_APPLICATION
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "d2702383b2e042ebefbb318f9382fd094c1c2d6b"
- AlgorithmId: sha256
Digest: "8fb6a4c7a0c7e7f22b944906eb07786cd3860394c7929e7c0768b2c99a2a3d87"
EventSize: 162
Event:
ImageLocationInMemory: 0x7adb3000
ImageLengthInMemory: 893720
ImageLinkTimeAddress: 0x0
LengthOfDevicePath: 130
DevicePath: "01041400b9731de684a3cc4aaeab82e828f3628b031d050002031d05000104012a0001000000009800000000000000f805000000000050641c65888b6b418f2257061a9dc3c50202040436005c004500460049005c00640065006200690061006e005c007300680069006d0061006100360034002e0065006600690000007fff0400"
- EventNum: 8
PCRIndex: 1
EventType: Unknown event type
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "50eb6bd100c48e81644d666a437725f49c6aed3c"
- AlgorithmId: sha256
Digest: "eb881b78feeb95756141a8d5358b891b297fad61b296f667de1f59b66bc92f4f"
EventSize: 52
Event: "61dfe48bca93d211aa0d00e098032b8c0900000000000000020000000000000042006f006f0074004f0072006400650072000000"
- EventNum: 9
PCRIndex: 1
EventType: Unknown event type
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "74e29a0674816dfdfc2c2e9cbbcec357132da4e8"
- AlgorithmId: sha256
Digest: "5d123811f51e2e46c437c7e88e07053c81f4e63da3f11de8a8a2afb5334db137"
EventSize: 198
Event: "61dfe48bca93d211aa0d00e098032b8c0800000000000000960000000000000042006f006f0074003000300030003000010000008200640065006200690061006e00000001041400b9731de684a3cc4aaeab82e828f3628b031d050002031d05000104012a0001000000009800000000000000f805000000000050641c65888b6b418f2257061a9dc3c50202040436005c004500460049005c00640065006200690061006e005c007300680069006d0061006100360034002e0065006600690000007fff0400"
- EventNum: 10
PCRIndex: 4
EventType: EV_EFI_ACTION
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "cd0fdb4531a6ec41be2753ba042637d6e5f7f256"
- AlgorithmId: sha256
Digest: "3d6772b4f84ed47595d72a2c4c5ffd15f5bb72c7507fe26f2aaee2c69d5633ba"
EventSize: 40
Event: 'Calling EFI Application from Boot Option'
- EventNum: 11
PCRIndex: 0
EventType: EV_SEPARATOR
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "9069ca78e7450a285173431b3e52c5c25299e473"
- AlgorithmId: sha256
Digest: "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
EventSize: 4
Event: "00000000"
- EventNum: 12
PCRIndex: 1
EventType: EV_SEPARATOR
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "9069ca78e7450a285173431b3e52c5c25299e473"
- AlgorithmId: sha256
Digest: "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
EventSize: 4
Event: "00000000"
- EventNum: 13
PCRIndex: 2
EventType: EV_SEPARATOR
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "9069ca78e7450a285173431b3e52c5c25299e473"
- AlgorithmId: sha256
Digest: "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
EventSize: 4
Event: "00000000"
- EventNum: 14
PCRIndex: 3
EventType: EV_SEPARATOR
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "9069ca78e7450a285173431b3e52c5c25299e473"
- AlgorithmId: sha256
Digest: "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
EventSize: 4
Event: "00000000"
- EventNum: 15
PCRIndex: 4
EventType: EV_SEPARATOR
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "9069ca78e7450a285173431b3e52c5c25299e473"
- AlgorithmId: sha256
Digest: "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
EventSize: 4
Event: "00000000"
- EventNum: 16
PCRIndex: 5
EventType: EV_SEPARATOR
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "9069ca78e7450a285173431b3e52c5c25299e473"
- AlgorithmId: sha256
Digest: "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
EventSize: 4
Event: "00000000"
- EventNum: 17
PCRIndex: 6
EventType: EV_SEPARATOR
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "9069ca78e7450a285173431b3e52c5c25299e473"
- AlgorithmId: sha256
Digest: "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
EventSize: 4
Event: "00000000"
- EventNum: 18
PCRIndex: 7
EventType: EV_SEPARATOR
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "9069ca78e7450a285173431b3e52c5c25299e473"
- AlgorithmId: sha256
Digest: "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119"
EventSize: 4
Event: "00000000"
- EventNum: 19
PCRIndex: 5
EventType: EV_EFI_ACTION
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "443a6b7b82b7af564f2e393cd9d5a388b7fa4a98"
- AlgorithmId: sha256
Digest: "d8043d6b7b85ad358eb3b6ae6a873ab7ef23a26352c5dc4faa5aeedacf5eb41b"
EventSize: 29
Event: 'Exit Boot Services Invocation'
- EventNum: 20
PCRIndex: 5
EventType: EV_EFI_ACTION
DigestCount: 2
Digests:
- AlgorithmId: sha1
Digest: "475545ddc978d7bfd036facc7e2e987f48189f0d"
- AlgorithmId: sha256
Digest: "b54f7542cbd872a81a9d9dea839b2b8d747c7ebd5ea6615c40f42f44a6dbeba0"
EventSize: 40
Event: 'Exit Boot Services Returned with Success'
pcrs:
sha1:
0 : 0x3e26be54f5f15140afbe509cc4580538d979598d
1 : 0x5b4c188c39baa249f688460a63b68df6d3d3ec94
2 : 0xb2a83b0ebf2f8374299a5b2bdfc31ea955ad7236
3 : 0xb2a83b0ebf2f8374299a5b2bdfc31ea955ad7236
4 : 0x260ae65533f38ab643f157bd176c72f9fdece410
5 : 0xd16d7e629fd8d08ca256f9ad3a3a1587c9e6cc1b
6 : 0xb2a83b0ebf2f8374299a5b2bdfc31ea955ad7236
7 : 0x518bd167271fbb64589c61e43d8c0165861431d8
sha256:
0 : 0x7f35c1ef1bb7b9d2aee58ec4c36cf384d70524c2ce2b6801772d7fdb1d2b5f5a
1 : 0xf35b74319598e48a6a69a6a04e903a872558b891563b0af23c877c8472c277a6
2 : 0x3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969
3 : 0x3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969
4 : 0xbe4d7464e3a3c0a04040355368006a5fbe02c0ef232c8c18926df9b718374f36
5 : 0xa5ceb755d043f32431d63e39f5161464620a3437280494b5850dc1b47cc074e0
6 : 0x3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969
7 : 0x65caf8dd1e0ea7a6347b635d2b379c93b9a1351edc2afc3ecda700e534eb3068